package com.zshan.clinic.common.util.crypto;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.util.Base64;

/**
 * @author lichen
 */
public class CryptoUtils {

    private static final String AES = "AES";
    private static final String MD5 = "MD5";


    public static String generateAESKey() throws Exception {
        KeyGenerator keyGen = KeyGenerator.getInstance(AES);
        keyGen.init(128); // 128位AES密钥
        SecretKey secretKey = keyGen.generateKey();
        byte[] encoded = secretKey.getEncoded();
        return Base64.getEncoder().encodeToString(encoded);
    }

    // --- 常用编码辅助 ---
    private static String bytesToHex(byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        for(byte b : bytes) {
            sb.append(String.format("%02x", b & 0xff));
        }
        return sb.toString();
    }

    // --- 摘要算法 ---

    /** MD5摘要 */
    public static String md5(String data){
        try {
            MessageDigest md = MessageDigest.getInstance(MD5);
            byte[] hash = md.digest(data.getBytes(StandardCharsets.UTF_8));
            return bytesToHex(hash);
        } catch (Exception e) {
        }
        return data;
    }

    /** SHA-256摘要 */
    public static String sha256(String data) throws Exception {
        MessageDigest md = MessageDigest.getInstance("SHA-256");
        byte[] hash = md.digest(data.getBytes(StandardCharsets.UTF_8));
        return bytesToHex(hash);
    }

    // --- AES对称加密/解密 ---
    public static String aesEncrypt(String data, String base64Key) throws Exception {
        byte[] keyBytes = Base64.getDecoder().decode(base64Key);
        SecretKeySpec secretKey = new SecretKeySpec(keyBytes, AES);
        Cipher cipher = Cipher.getInstance(AES);
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);
        byte[] encrypted = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
        return Base64.getEncoder().encodeToString(encrypted);
    }




    /**
     * AES解密
     * @param encryptedData Base64编码的密文
     * @param base64Key Base64编码的密钥字符串
     * @return 明文字符串
     * @throws Exception
     */
    public static String aesDecrypt(String encryptedData, String base64Key) throws Exception {
        byte[] keyBytes = Base64.getDecoder().decode(base64Key);
        SecretKeySpec secretKey = new SecretKeySpec(keyBytes, AES);
        Cipher cipher = Cipher.getInstance(AES);
        cipher.init(Cipher.DECRYPT_MODE, secretKey);
        byte[] decodedEncryptedData = Base64.getDecoder().decode(encryptedData);
        byte[] decrypted = cipher.doFinal(decodedEncryptedData);
        return new String(decrypted, StandardCharsets.UTF_8);
    }

    // --- RSA非对称加密/解密 ---

    public static KeyPair generateRSAKeyPair() throws Exception {
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        keyPairGenerator.initialize(2048);
        return keyPairGenerator.generateKeyPair();
    }

    public static String rsaEncrypt(String data, PublicKey publicKey) throws Exception {
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        byte[] encrypted = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
        return Base64.getEncoder().encodeToString(encrypted);
    }

    public static String rsaDecrypt(String encryptedData, PrivateKey privateKey) throws Exception {
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] decoded = Base64.getDecoder().decode(encryptedData);
        byte[] decrypted = cipher.doFinal(decoded);
        return new String(decrypted, StandardCharsets.UTF_8);
    }

    public static void main(String[] args) throws Exception {

        String originalText = "Hello, CryptoUtils!";

        System.out.println("原始文本: " + originalText);

        // ==== MD5 ====
        String md5Hash = CryptoUtils.md5(originalText);
        System.out.println("MD5: " + md5Hash);

        // ==== SHA-256 ====
        String sha256Hash = CryptoUtils.sha256(originalText);
        System.out.println("SHA-256: " + sha256Hash);

        // ==== AES加密解密 ====
        String aesKey = CryptoUtils.generateAESKey(); // 生成AES密钥
        System.out.println("AES密钥: " + aesKey);

        String aesEncrypted = CryptoUtils.aesEncrypt(originalText, aesKey);
        System.out.println("AES加密后: " + aesEncrypted);

        String aesDecrypted = CryptoUtils.aesDecrypt(aesEncrypted, aesKey);
        System.out.println("AES解密后: " + aesDecrypted);

        // ==== RSA加密解密 ====
        KeyPair rsaKeyPair = CryptoUtils.generateRSAKeyPair();

        System.out.println("RSA公钥: " + rsaKeyPair.getPublic());
        System.out.println("RSA私钥: " + rsaKeyPair.getPrivate());

        String rsaEncrypted = CryptoUtils.rsaEncrypt(originalText, rsaKeyPair.getPublic());
        System.out.println("RSA加密后: " + rsaEncrypted);

        String rsaDecrypted = CryptoUtils.rsaDecrypt(rsaEncrypted, rsaKeyPair.getPrivate());
        System.out.println("RSA解密后: " + rsaDecrypted);
    }



}
